package cn.car.web.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 *  使用gizp的压缩流对象---用来装饰Response
 *  目的: 压缩了图片,js,css等静态资源,提高了传输率
 * @author wxs
 */
public class GzipWrapper extends HttpServletResponseWrapper {
	//当前流的方式:无,字符,字节
	public static final int OT_NONE = 0,OT_WRITER= 1,OT_STREAM = 2;
	//当前流的方式
    private int outputType = OT_NONE;
    //两个流
    private ServletOutputStream output = null;
    private PrintWriter writer = null;
    //缓存字节数组输出流
    private ByteArrayOutputStream buffer = null;
	
	public GzipWrapper(HttpServletResponse response) {
		super(response);
		buffer = new ByteArrayOutputStream();
	}

	/**
	 * 获取字符的输出流
	 */
	@Override
	public PrintWriter getWriter() throws IOException {
		//如果输出方式是字节型,则抛出异常
		if(outputType == OT_STREAM){
			throw new IllegalStateException();
		}else if(outputType == OT_WRITER){
			return writer;
		}else{
			outputType = OT_WRITER;
			writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding()));
			
			return writer;
		}
		
	}
	/**
	 * 获取字节的输出流
	 */
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		//如果输出方式是字节型,则抛出异常
				if(outputType == OT_WRITER){
					throw new IllegalStateException();
				}else if(outputType == OT_STREAM){
					return output;
				}else{
					outputType = OT_STREAM;
					output = new WrappedOutputStream(buffer);
					return output;
				}
	}

	@Override
	public void flushBuffer() throws IOException {
		if(outputType == OT_WRITER){
			writer.flush();
		}else if(outputType ==OT_STREAM){
			output.flush();
		}
	}

	/**
	 * 重置流
	 */
	@Override
	public void reset() {
		outputType =OT_NONE;
		buffer.reset();
	}
	
	public byte[] getResponseData() throws IOException{
		flushBuffer();
		return buffer.toByteArray();
	}
	
	/**
	 * 装饰字节的输出流 
	 * @author xs
	 */
	 class WrappedOutputStream extends ServletOutputStream {
	        private ByteArrayOutputStream buffer;

	        public WrappedOutputStream(ByteArrayOutputStream buffer) {
	            this.buffer = buffer;
	        }

	        public void write(int b) throws IOException {
	            buffer.write(b);
	        }

	        public byte[] toByteArray() {
	            return buffer.toByteArray();
	        }
	    }

}
